Using the pinch manipulator

Use the pinch manipulator to enable users to zoom and rotate nodes in your Kanzi application. For example, you can use the pinch manipulator to enable users to zoom into and out of a map. See Enabling the pinch gesture for a node.

Use the Pinch Manipulator triggers to react to the pinch gesture. For example, you can set the appearance of a node when the user zooms and rotates the node using the pinch gesture. See Using the Pinch Manipulator triggers.

The pinch manipulator is one of the input manipulators you can use to add gesture recognition to nodes in your Kanzi application. You can assign the input manipulators through the Kanzi Engine API. See Using input manipulators.

Learn how to use the pinch manipulator by completing a tutorial. See Tutorial: Pan, zoom, tap.

Enabling the pinch gesture for a node

To enable the pinch gesture for a node:

  1. In Kanzi Studio create a project using the Application template.
  2. In the Project create a node for which you want to enable the pinch gesture.
    For example, create an Image node and name it PinchNode.
  3. In the Project select the node you created in the previous step, in the Properties add the Hit Testable property, and set it to enabled.
    When you enable this property you enable the user to pick a node.
    By default hit testing is enabled for the Button, List Box Item Container, Scroll View, and Slider nodes. See Defining which node receives user input.
  4. In the Project press Alt and right-click the node you created and select Alias.
    Kanzi Studio creates an alias pointing to the node from which you created the alias and adds it to the resource dictionary of its nearest ancestor node that contains a resource dictionary.
    Access alias target nodes using the # sign followed by the name of the alias.
  5. Select File > Export > Export KZB.
    Kanzi Studio creates the kzb file and configuration files from your Kanzi Studio project. Kanzi Studio stores the exported files in the <ProjectName>/Application/bin directory or the location you specify in the Binary Export Directory property in Project > Properties. The kzb file contains all nodes and resources from your Kanzi Studio project, except the resources you mark in a localization table as locale packs.
    When you run your Kanzi application from Visual Studio, your application loads the kzb file and configuration files.
  6. In Visual Studio open the solution stored in <ProjectName>/Application/configs/platforms/win32 and in the file which implements the logic of your application create and configure the pinch manipulator:
    1. Define the handlers for the pinch messages.
      For example, after the public section of the class which implements the logic of your application add:
      private:
      
          // Define the handler for the PinchManipulator::StartedMessage message from the 2D nodes 
          // that have an input manipulator which generates pinch messages.
          // This handler prepares a 2D node for a pinch gesture.
          void onPinchStarted(PinchManipulator::StartedMessageArguments& messageArguments)
          {
              // Get from the message arguments the node that the user pinches.
              Node2DSharedPtr node2d = dynamic_pointer_cast<Node2D>(messageArguments.getSource());
      
              if (!node2d)
              {
                  return;
              }
      
              // When starting a pinch gesture on the node, bring the node to front.
              node2d->moveToFront();
      
              // Store the initial value of the Render Transformation scale.
              SRTValue2D nodeTransform = node2d->getRenderTransformation();
              m_pinchInitialScaleFactor = nodeTransform.getScale().getX() - 1.0f;
          }
      
          // Define the handler for the PinchManipulator::MovedMessage message from the 2D nodes
          // that have an input manipulator which generates pinch messages.
          // This scales and rotates a 2D node for the amount of the pinch gesture.
          void onPinchMoved(PinchManipulator::MovedMessageArguments& messageArguments)
              {
              // Get from the message arguments the node that the user pinches.
              Node2DSharedPtr node2d = dynamic_pointer_cast<Node2D>(messageArguments.getSource());
      
              if (!node2d)
              {
                  return;
              }
      
              float scale;
      
              // Get the scale and rotation from the message arguments.
              float scaleDelta = messageArguments.getScale();
              float rotateDelta = messageArguments.getRotation();
      
              // Get the Render Transformation property of the node.
              SRTValue2D nodeTransform = node2d->getRenderTransformation();
      
              // Calculate the scale by adding the initial scale to the pinch value.
              scale = scaleDelta + m_pinchInitialScaleFactor;
      
              // Apply the rotation.
              nodeTransform.rotate(rotateDelta);
      
              // Apply the scale.
              nodeTransform.setScale(Vector2(scale, scale));
      
              // To make the node rotate around its center instead of its upper left corner,
              // set the Render Transformation Origin property to (0.5, 0.5).
              node2d->setRenderTransformationOrigin(Vector2(0.5f, 0.5f));
      
              // Apply the new transform to the node.
              node2d->setRenderTransformation(nodeTransform);
          }
      
          // Initial scale factor for the pinch gesture.
          float m_pinchInitialScaleFactor;
    2. In the public section of the class which implements the logic of your application, add the constructor and set the initial scale factor for the pinch gesture:
          MyProject() :
              m_pinchInitialScaleFactor(0.0f)
          {
          }
    3. In the onProjectLoaded() function create a PinchManipulator manipulator and subscribe to its messages.
      For example, add:
          virtual void onProjectLoaded() KZ_OVERRIDE
          {
              ScreenSharedPtr screen = getScreen();
              Domain* domain = getDomain();
      
              // Get the PinchNode node using its alias.
              NodeSharedPtr pinchNode = screen->lookupNode<Node>("#PinchNode");
      
              // Create an input manipulator that generates pinch messages.
              PinchManipulatorSharedPtr pinchManipulator = PinchManipulator::create(domain);
      
              // Add the input manipulator to the PinchNode.
              pinchNode->addInputManipulator(pinchManipulator);
      
              // Subscribe to the PinchManipulator::StartedMessage message at the PinchNode.
              // The PinchManipulator generates this message when the user presses two fingers on the attached node.
              pinchNode->addMessageHandler(PinchManipulator::StartedMessage, bind(&MyProject::onPinchStarted, this, placeholders::_1));
      
              // Subscribe to the PinchManipulator::MovedMessage message at the PinchNode.
              // The PinchManipulator generates this message first when the scale or rotation threshold is exceeded
              // and after that when the tracked touches have moved between updates.
              pinchNode->addMessageHandler(PinchManipulator::MovedMessage, bind(&MyProject::onPinchMoved, this, placeholders::_1));
         }
  7. Build and run your application. See Deploying Kanzi applications.
    In the application zoom and rotate the node for which you enabled the pinch gesture.

Using the Pinch Manipulator triggers

Use the Pinch Manipulator triggers to react to the pinch gesture. For example, you can set the appearance of a node when the user zooms and rotates the node using the pinch gesture.

The Pinch Manipulator has these triggers:

To use the Pinch Manipulator triggers:

  1. Enable the pinch gesture for a node. See Enabling the pinch gesture for a node.
  2. Define the behavior that you want to set with the Pinch Manipulator triggers.
    For example, create a state manager where you define the states which set the appearance of a node when the Pinch Moved and Pinch Finished triggers are set off. See Creating a state manager.
  3. Add and configure a Pinch Manipulator trigger:
    1. In the Project select the node to which you want to add the trigger, and in the Node Components > Triggers section add one of the Pinch Manipulator triggers.
      For example, in the Project select the node for which you enabled the pinch gesture and in the Node Components add the Pinch Moved trigger.
    2. In the trigger you created in the previous step click Trigger Settings and in the Trigger Settings Editor disable the Set Message Handled property.
      When you disable the Set Message Handled property, this trigger intercepts the message, but does not stop it. This way you let the input manipulator handle the message.
    3. In the trigger you created, in the Add dropdown menu select an action and configure it.
      For example, select the Go to State action, and in the action settings set:
      • Item to the node for which you enabled the pinch gesture
      • State to the state which sets the appearance of the node when the Pinch Moved trigger is set off
  4. Repeat the previous step to add and configure more Pinch Manipulator triggers.
    For example, add the Pinch Finished trigger, and in the Go to State action of the trigger set State to the state which sets the appearance of the node when that trigger is set off.
  5. Select File > Export > Export KZB.
  6. Build and run your application. See Deploying Kanzi applications.
    In the application zoom and rotate the node for which you enabled the pinch gesture.

Using the pinch manipulator in the API

For details, see the PinchManipulator class in the API reference.

See also

Tutorial: Pan, zoom, tap

Handling user input

Using the pan manipulator

Using the Scroll View nodes

Deploying Kanzi applications

Using triggers